066754
@@ -46,6 +46,7 @@
import org.springframework.beans.factory.InitializingBean;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ApplicationListener;
+import org.springframework.context.SmartLifecycle;
 import org.springframework.context.event.ContextClosedEvent;
 import org.springframework.util.Assert;
 import org.springframework.util.StringUtils;
@@ -85,7 +86,7 @@
import com.rabbitmq.client.ShutdownSignalException;
  */
 public class CachingConnectionFactory extends AbstractConnectionFactory
 		implements InitializingBean, ShutdownListener, ApplicationContextAware, ApplicationListener<ContextClosedEvent>,
-				PublisherCallbackChannelConnectionFactory {
+				PublisherCallbackChannelConnectionFactory, SmartLifecycle {
 
 	private ApplicationContext applicationContext;
 
@@ -134,8 +135,14 @@
public class CachingConnectionFactory extends AbstractConnectionFactory
 
 	private volatile boolean initialized;
 
+	private volatile boolean contextStopped;
+
 	private volatile boolean stopped;
 
+	private volatile boolean running;
+
+	private int phase = Integer.MIN_VALUE + 1000;
+
 	private volatile ConditionalExceptionLogger closeExceptionLogger = new DefaultChannelCloseLogger();
 
 	/** Synchronization monitor for the shared Connection */
@@ -327,8 +334,7 @@
public class CachingConnectionFactory extends AbstractConnectionFactory
 	@Override
 	public void onApplicationEvent(ContextClosedEvent event) {
 		if (this.applicationContext == event.getApplicationContext()) {
-			this.stopped = true;
-			this.deferredCloseExecutor.shutdownNow();
+			this.contextStopped = true;
 		}
 	}
 
@@ -579,6 +585,60 @@
public class CachingConnectionFactory extends AbstractConnectionFactory
 		}
 	}
 
+	@Override
+	public void start() {
+		this.running = true;
+	}
+
+	@Override
+	public boolean isRunning() {
+		return this.running;
+	}
+
+	@Override
+	public int getPhase() {
+		return this.phase;
+	}
+
+	/**
+	 * Defaults to phase {@link Integer#MIN_VALUE - 1000} so the factory is
+	 * stopped in a very late phase, allowing other beans to use the connection
+	 * to clean up.
+	 * @see #getPhase()
+	 * @param phase the phase.
+	 * @since 1.5.3
+	 */
+	public void setPhase(int phase) {
+		this.phase = phase;
+	}
+
+	@Override
+	public boolean isAutoStartup() {
+		return true;
+	}
+
+	/**
+	 * Stop the connection factory to prevent its connection from being used.
+	 * Note: ignored unless the application context is in the process of being stopped.
+	 */
+	@Override
+	public void stop() {
+		if (this.contextStopped) {
+			this.running = false;
+			this.stopped = true;
+			this.deferredCloseExecutor.shutdownNow();
+		}
+		else {
+			logger.warn("stop() is ignored unless the application context is being stopped");
+		}
+	}
+
+	@Override
+	public void stop(Runnable callback) {
+		stop();
+		callback.run();
+	}
+
 	/*
 	 * Reset the Channel cache and underlying shared Connection, to be reinitialized on next access.
 	 */
